#include <iostream>
#include "afxdb.h"
#include "person.h"

using namespace std;

int retrieve_record();
int update_record();

int main (void) {

	cout << "Hello world!" << endl;

	update_record();
	retrieve_record();

}

int retrieve_record(){
	Cperson rs;
	//rs.Open( CRecordset::forwardOnly, _T( "SELECT * FROM person" ) );
	rs.Open(CRecordset::forwardOnly, NULL, CRecordset::none);
	cout << "Cperson default SQL: " << rs.GetDefaultSQL() << endl;
	cout << "Cperson default connection: " << rs.GetDefaultConnect() << endl;
	cout << "Cperson no of records : " << rs.GetRecordCount() << endl;

	// Loop through the recordset,

	short nFields = rs.GetODBCFieldCount( );
	cout << "number of fields is " << nFields << endl;
	while( !rs.IsEOF( ) )
	{
		cout << "ID        : " << rs.m_per_id<< endl;
		cout << "First Name: " << rs.m_per_firstname<< endl;
		cout << "Last Name : " << rs.m_per_lastname<< endl;
		cout << "Email     : " << rs.m_per_email<< endl;
		//cout << "CLongBinary     : " << rs.m_per_photo << endl;

        CString strFileName = "D:\\DIS\\1";

        CFile	outFile(strFileName,CFile::modeCreate|CFile::modeWrite);
        LPSTR	buffer = (LPSTR)GlobalLock(rs.m_per_photo.m_hData);
        outFile.Write(buffer, rs.m_per_photo.m_dwDataLength);
        GlobalUnlock(rs.m_per_photo.m_hData);
        outFile.Close();

		cout << "*** end of one row! ***" << endl;
		rs.MoveNext( );
	}

	rs.Close( );
	return 0;
}

int update_record () {
	Cperson rs; 
	rs.Open();

	if (rs.CanUpdate() == FALSE ) {
		cout << "record cannot be updated!" << endl;
		return 1;
	}
	
	while( !rs.IsEOF( ) ) {
		if (rs.m_per_id == 1) {
			rs.Edit();
			//rs.m_per_firstname = _T("HELLO");
	
		    CFile	fileImage;
			CFileStatus	fileStatus;

			fileImage.Open(_T("D:\\DIS\\you.dao.li.gif"), CFile::modeRead);
			fileImage.GetStatus(fileStatus);

			rs.m_per_photo.m_dwDataLength = (SQLUINTEGER)fileStatus.m_size;

			cout << "image in bytes: " << rs.m_per_photo.m_dwDataLength << endl;
			HGLOBAL hGlobal		= GlobalAlloc(GPTR,(SIZE_T)fileStatus.m_size);
			//rs.m_per_photo.m_hData = GlobalAlloc(GPTR,fileStatus.m_size);
			rs.m_per_photo.m_hData = GlobalLock(hGlobal);
			//LPVOID buffer = GlobalLock(rs.m_per_photo.m_hData); 

			fileImage.Read(rs.m_per_photo.m_hData,(UINT)fileStatus.m_size);
			//fileImage.Read(buffer, fileStatus.m_size); 

			// In order for a CLongBinary field to be included in an update, you must explicitly call SetFieldDirty for the field. If you make any change to a field, including setting it Null, you must call SetFieldDirty. You must also call SetFieldNull, with the second parameter being FALSE, to mark the field as having a value. 

			rs.SetFieldDirty(&rs.m_per_photo);
			rs.SetFieldNull(&rs.m_per_photo,FALSE);
			
			
			if (!rs.Update()) {
				cout << "update record failed!" << endl;
				return 1;
			}	
			GlobalUnlock(hGlobal);
		}
		rs.MoveNext();
	} // end of while loop
	
	rs.Close();
	return 0;
}



